﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls.Primitives;
using System.Windows.Media.Imaging;

namespace G.Animation
{
    public class TileFlipAnimation : BaseAnimation
    {
        //private FrameworkElement[] elementList;
        private FrameworkElement targetElement;
        public TileFlipAnimation(IEnumerable<FrameworkElement> elements, FrameworkElement targetElement)
            : base(elements)
        {
            this.targetElement = targetElement;
        }

        /// <summary>
        /// 类似手机开始桌面翻转动画，有翻入和翻出的效果
        /// </summary>
        /// <param name="elements"></param>
        /// <param name="targetElement"></param>
        /// <param name="directions"></param>
        /// <param name="featherDelay">项之间间隔的时间差,数值越小动画越快</param>
        public void TileFlip(Action callBack = null, Directions directions = Directions.Out, int featherDelay = 30)
        {
            double delay = 0;
            int timeCounter = 0;
            var elementList = this.ElementList.ToArray();
            for (int i = 0; i < elementList.Length; i++)
            {
                FrameworkElement element = elementList[i];
                PlaneProjection pp = new PlaneProjection();
                pp.CenterOfRotationX = 0;
                element.Projection = pp;

                CompositeTransform ct = new CompositeTransform();
                element.RenderTransform = ct;

                if (i % 2 == 1)
                {
                    element.Projection.SetValue(PlaneProjection.CenterOfRotationXProperty, -1.0);
                }

                if (element == targetElement)
                {
                    delay = featherDelay * elementList.Length;
                    Storyboard sb = null;
                    sb = GetTileFlipAnimation(element, delay, directions);
                    if (callBack != null)
                    {
                        sb.Completed += (s, e) =>
                        {
                            callBack();
                        };
                    }
                    sb.Begin();
                }
                else
                {
                    delay = featherDelay * timeCounter;
                    timeCounter++;
                    GetTileFlipAnimation(element, delay, directions).Begin();
                }
            }
        }


        private Storyboard GetTileFlipAnimation(FrameworkElement element, double delay, Directions directions)
        {
            Storyboard sb = new Storyboard();
            TimeSpan beginTime = TimeSpan.FromMilliseconds(delay);

            if (directions == Directions.Out)
            {
                element.Opacity = 1;
                DoubleAnimation da = new DoubleAnimation();
                da.BeginTime = beginTime;
                da.Duration = TimeSpan.FromMilliseconds(250);
                da.To = 50;
                ExponentialEase ee = new ExponentialEase();
                ee.EasingMode = EasingMode.EaseIn;
                ee.Exponent = 6;
                da.EasingFunction = ee;
                Storyboard.SetTarget(da, element);
                Storyboard.SetTargetProperty(da, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationY)"));
                sb.Children.Add(da);

                da = new DoubleAnimation();
                da.Duration = TimeSpan.FromMilliseconds(10);
                da.To = 0;
                da.BeginTime = TimeSpan.FromMilliseconds(250).Add(beginTime);
                Storyboard.SetTarget(da, element);
                Storyboard.SetTargetProperty(da, new PropertyPath("(UIElement.Opacity)"));
                sb.Children.Add(da);
            }
            else
            {
                element.Opacity = 0;

                DoubleAnimationUsingKeyFrames daukf = new DoubleAnimationUsingKeyFrames();

                EasingDoubleKeyFrame edkf1 = new EasingDoubleKeyFrame();
                edkf1.KeyTime = beginTime;
                edkf1.Value = -80;
                daukf.KeyFrames.Add(edkf1);

                EasingDoubleKeyFrame edkf2 = new EasingDoubleKeyFrame();
                edkf2.KeyTime = TimeSpan.FromMilliseconds(350).Add(beginTime);
                edkf2.Value = 0;

                ExponentialEase ee = new ExponentialEase();
                ee.EasingMode = EasingMode.EaseOut;
                ee.Exponent = 6;

                edkf2.EasingFunction = ee;
                daukf.KeyFrames.Add(edkf2);

                Storyboard.SetTarget(daukf, element);
                Storyboard.SetTargetProperty(daukf, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationY)"));
                sb.Children.Add(daukf);

                DoubleAnimation da = new DoubleAnimation();
                da.Duration = TimeSpan.FromMilliseconds(0);
                da.BeginTime = beginTime;
                da.To = 1;

                Storyboard.SetTarget(da, element);
                Storyboard.SetTargetProperty(da, new PropertyPath("(UIElement.Opacity)"));
                sb.Children.Add(da);
            }
            return sb;
        }
   
        //public override void Reset()
        //{
        //    base.Reset();
        //    //this.TileFlip(null, Directions.In, 50);
        //}
    }
}
